""" -*- mode: python; coding: utf-8; -*-

    Copyright 2008 Asier Aguirre <asier.aguirre@gmail.com>
    This file is part of Intromit.

    Intromit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Intromit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Intromit.  If not, see <http://www.gnu.org/licenses/>.
"""

import sys, python_config, pyintromit, unittest, python_runner
pyintromit.load("intromit/test/.libs/libpython_methods.so")
import libpython_methods


class test_3_methods(unittest.TestCase):

    def setUp(self):
        self.uut=libpython_methods.python_methods()

    def test_01(self):
        "Call void function"
        try: self.uut.sample_void()
        except: self.fail("Call to void(void) function")

    def test_02(self):
        "Call add function typed: int"
        try: add=self.uut.add_int(-1, -2)
        except: self.fail("Call to add function: int")
        self.assertEqual(add, -3, "Result of add int")

    def test_03(self):
        "Call add function typed: unsigned"
        try: add=self.uut.add_unsigned(1, 2)
        except: self.fail("Call to add function: unsigned")
        self.assertEqual(add, 3, "Result of add unsigned")

    def test_04(self):
        "Call add function typed: short"
        try: add=self.uut.add_short(-1, -2)
        except: self.fail("Call to add function: short")
        self.assertEqual(add, -3, "Result of add short")

    def test_05(self):
        "Call add function typed: ushort"
        try: add=self.uut.add_ushort(1, 2)
        except: self.fail("Call to add function: ushort")
        self.assertEqual(add, 3, "Result of add ushort")

    def test_06(self):
        "Call add function typed: char"
        try: add=self.uut.add_char(-1, -2)
        except: self.fail("Call to add function: char")
        self.assertEqual(add, -3, "Result of add char")

    def test_07(self):
        "Call add function typed: uchar"
        try: add=self.uut.add_uchar(1, 2)
        except: self.fail("Call to add function: uchar")
        self.assertEqual(add, 3, "Result of add uchar")

    def test_08(self):
        "Call add function typed: longlong"
        try: add=self.uut.add_longlong(-1, -2)
        except: self.fail("Call to add function: longlong")
        self.assertEqual(add, -3, "Result of add longlong")

    def test_09(self):
        "Call add function typed: ulonglong"
        try: add=self.uut.add_ulonglong(1, 2)
        except: self.fail("Call to add function: ulonglong")
        self.assertEqual(add, 3, "Result of add ulonglong")

    def test_10(self):
        "Call add function typed: float"
        try: add=self.uut.add_float(1, 2)
        except: self.fail("Call to add function: float")
        self.assertAlmostEqual(add, 3, 1, "Result of add float")

    def test_11(self):
        "Call add function typed: double"
        try: add=self.uut.add_double(1, 2)
        except: self.fail("Call to add function: double")
        self.assertAlmostEqual(add, 3, 1, "Result of add double")

    def test_12(self):
        "Method return value limits: int"
        self.assertEqual(self.uut.add_int(2147483646, 1), 2147483647, "Limit ret > int")
        self.assertEqual(self.uut.add_int(-2147483647, -1), -2147483648, "Limit ret < int")
        self.assertEqual(self.uut.add_int(2147483646, 2), -2147483648, "Limit ret >> int")
        self.assertEqual(self.uut.add_int(-2147483647, -2), 2147483647, "Limit ret << int")

    def test_13(self):
        "Method return value limits: unsigned"
        self.assertEqual(self.uut.add_unsigned(4294967294L, 1), 4294967295L, "Limit ret > unsigned")
        self.assertEqual(self.uut.add_unsigned(4294967294L, 2), 0, "Limit ret >> unsigned")

    def test_14(self):
        "Method return value limits: short"
        self.assertEqual(self.uut.add_short(32766, 1), 32767, "Limit ret > short")
        self.assertEqual(self.uut.add_short(-32767, -1), -32768, "Limit ret < short")
        self.assertEqual(self.uut.add_short(32766, 2), -32768, "Limit ret >> short")
        self.assertEqual(self.uut.add_short(-32767, -2), 32767, "Limit ret << short")

    def test_15(self):
        "Method return value limits: ushort"
        self.assertEqual(self.uut.add_ushort(65534, 1), 65535, "Limit ret > ushort")
        self.assertEqual(self.uut.add_ushort(65534, 2), 0, "Limit ret >> ushort")

    def test_16(self):
        "Method return value limits: char"
        self.assertEqual(self.uut.add_char(126, 1), 127, "Limit ret > char")
        self.assertEqual(self.uut.add_char(-127, -1), -128, "Limit ret < char")
        self.assertEqual(self.uut.add_char(126, 2), -128, "Limit ret >> char")
        self.assertEqual(self.uut.add_char(-127, -2), 127, "Limit ret << char")

    def test_17(self):
        "Method return value limits: uchar"
        self.assertEqual(self.uut.add_uchar(254, 1), 255, "Limit ret > uchar")
        self.assertEqual(self.uut.add_uchar(254, 2), 0, "Limit ret >> uchar")

    def test_18(self):
        "Method return value limits: longlong"
        self.assertEqual(self.uut.add_longlong(9223372036854775806L, 1), 9223372036854775807L, "Limit ret > longlong")
        self.assertEqual(self.uut.add_longlong(-9223372036854775807L, -1), -9223372036854775808L, "Limit ret < longlong")
        self.assertEqual(self.uut.add_longlong(9223372036854775806L, 2), -9223372036854775808L, "Limit ret >> longlong")
        self.assertEqual(self.uut.add_longlong(-9223372036854775807L, -2), 9223372036854775807L, "Limit ret << longlong")

    def test_19(self):
        "Method return value limits: ulonglong"
        self.assertEqual(self.uut.add_ulonglong(18446744073709551614L, 1), 18446744073709551615L, "Limit ret > ulonglong")
        self.assertEqual(self.uut.add_ulonglong(18446744073709551614L, 2), 0, "Limit ret >> ulonglong")

    def test_20(self):
        "Bad arguments must fail: int"
        self.assertRaises(TypeError, self.uut.add_int, 2147483648, 0)
        self.assertRaises(TypeError, self.uut.add_int, -2147483649, 0)
        self.assertRaises(TypeError, self.uut.add_int, 1.0, 0)
        self.assertRaises(TypeError, self.uut.add_int, "hello", 0)

    def test_21(self):
        "Bad arguments must fail: unsigned"
        self.assertRaises(TypeError, self.uut.add_unsigned, 4294967296L, 0)
        self.assertRaises(TypeError, self.uut.add_unsigned, -1, 0)
        self.assertRaises(TypeError, self.uut.add_unsigned, 1.0, 0)

    def test_22(self):
        "Bad arguments must fail: short"
        self.assertRaises(TypeError, self.uut.add_short, 32768, 0)
        self.assertRaises(TypeError, self.uut.add_short, -32769, 0)
        self.assertRaises(TypeError, self.uut.add_short, 1.0, 0)

    def test_23(self):
        "Bad arguments must fail: ushort"
        self.assertRaises(TypeError, self.uut.add_ushort, 65536, 0)
        self.assertRaises(TypeError, self.uut.add_ushort, -1, 0)
        self.assertRaises(TypeError, self.uut.add_ushort, 1.0, 0)

    def test_24(self):
        "Bad arguments must fail: char"
        self.assertRaises(TypeError, self.uut.add_char, 128, 0)
        self.assertRaises(TypeError, self.uut.add_char, -129, 0)
        self.assertRaises(TypeError, self.uut.add_char, 1.0, 0)

    def test_25(self):
        "Bad arguments must fail: uchar"
        self.assertRaises(TypeError, self.uut.add_uchar, 256, 0)
        self.assertRaises(TypeError, self.uut.add_uchar, -1, 0)
        self.assertRaises(TypeError, self.uut.add_uchar, 1.0, 0)

    def test_26(self):
        "Bad arguments must fail: longlong"
        self.assertRaises(TypeError, self.uut.add_longlong, 9223372036854775808L, 0)
        self.assertRaises(TypeError, self.uut.add_longlong, -9223372036854775809L, 0)
        self.assertRaises(TypeError, self.uut.add_longlong, 1.0, 0)

    def test_27(self):
        "Bad arguments must fail: ulonglong"
        self.assertRaises(TypeError, self.uut.add_ulonglong, 18446744073709551616L, 0)
        self.assertRaises(TypeError, self.uut.add_ulonglong, -1, 0)
        self.assertRaises(TypeError, self.uut.add_ulonglong, 1.0, 0)

    def test_28(self):
        "Static method"
        self.assertEqual(self.uut.sample_poly(), 3, "Static method call")

    def test_29(self):
        "Polymorphism using correct parameters"
        self.assertEqual(self.uut.sample_poly(), 3, "PoliCall 0")
        self.assertEqual(self.uut.poly_function, -1, "PoliCheck 0")
        self.assertEqual(self.uut.sample_poly(1, 2), None, "PoliCall 1")
        self.assertEqual(self.uut.poly_function, 1, "PoliCheck 1")
        self.assertEqual(self.uut.sample_poly(1, 2, 3, 1.5, 2.6), int(1+2+3+1.5+2.6), "PoliCall 2")
        self.assertEqual(self.uut.poly_function, 2, "PoliCheck 2")
        self.assertEqual(self.uut.sample_poly(5.6), 5, "PoliCall 3")
        self.assertEqual(self.uut.poly_function, 3, "PoliCheck 3")
        self.assertEqual(self.uut.sample_poly(3.0, 4), 12, "PoliCall 4")
        self.assertEqual(self.uut.poly_function, 4, "PoliCheck 4")

    def test_30(self):
        "Polymorphism using incorrect parameters"
        self.assertRaises(TypeError, self.uut.sample_poly, 0.0, 0.0, 0.0)
        self.assertRaises(TypeError, self.uut.sample_poly, "str")
        self.assertRaises(TypeError, self.uut.sample_poly, 0, 0, 0, 0)
        self.assertRaises(TypeError, self.uut.sample_poly, 0.0, 0, 0, 0, 0)

    def test_31(self):
        "Unary operator: -"
        self.assertEqual(-self.uut, 1, "Unary -")

    def test_32(self):
        "Unary operator: +"
        self.assertEqual(+self.uut, 2, "Unary +")

    def test_33(self):
        "Unary operator: ~"
        self.assertEqual(~self.uut, 3, "Unary ~")

    def test_34(self):
        "Unary operator: not"
        self.assertEqual(self.uut.oper_not(), 4, "Unary not")

    def test_35(self):
        "Unary operator: addr"
        self.assertEqual(self.uut.oper_addr(), 5, "Unary addr")

    def test_36(self):
        "Unary operator: inc pre"
        self.assertEqual(self.uut.oper_inc(), 6, "Unary inc")

    def test_37(self):
        "Unary operator: dec pre"
        self.assertEqual(self.uut.oper_dec(), 7, "Unary dec")

    def test_38(self):
        "Unary operator: inc"
        self.assertEqual(self.uut.oper_inc(0), 8, "Unary inc")

    def test_39(self):
        "Unary operator: dec"
        self.assertEqual(self.uut.oper_dec(0), 9, "Unary dec")

    def test_40(self):
        "Binary operator: +"
        self.assertEqual(self.uut+1, 11, "Binary +")

    def test_41(self):
        "Binary operator: -"
        self.assertEqual(self.uut-1, 12, "Binary -")

    def test_42(self):
        "Binary operator: *"
        self.assertEqual(self.uut*1, 13, "Binary *")

    def test_43(self):
        "Binary operator: /"
        self.assertEqual(self.uut/1, 14, "Binary /")

    def test_44(self):
        "Binary operator: %"
        self.assertEqual(self.uut%1, 15, "Binary %")

    def test_45(self):
        "Binary operator: ^"
        self.assertEqual(self.uut^1, 16, "Binary ^")

    def test_46(self):
        "Binary operator: &"
        self.assertEqual(self.uut&1, 17, "Binary &")

    def test_47(self):
        "Binary operator: |"
        self.assertEqual(self.uut|1, 18, "Binary |")

    def test_48(self):
        "Binary operator: <<"
        self.assertEqual(self.uut<<1, 19, "Binary <<")

    def test_49(self):
        "Binary operator: >>"
        self.assertEqual(self.uut>>1, 20, "Binary >>")

    def test_50(self):
        "Binary operator: assign"
        self.assertEqual(self.uut.oper_assign(1), 21, "Binary assign")

    def test_51(self):
        "Inline operator: +="
        self.uut+=1

    def test_52(self):
        "Inline operator: -="
        self.uut-=1

    def test_53(self):
        "Inline operator: *="
        self.uut*=1

    def test_54(self):
        "Inline operator: /="
        self.uut/=1

    def test_55(self):
        "Inline operator: %="
        self.uut%=1

    def test_56(self):
        "Inline operator: ^="
        self.uut^=1

    def test_57(self):
        "Inline operator: &="
        self.uut&=1

    def test_58(self):
        "Inline operator: |="
        self.uut|=1

    def test_59(self):
        "Inline operator: <<="
        self.uut<<=1

    def test_60(self):
        "Inline operator: >>="
        self.uut>>=1

    def test_61(self):
        "Inline operator: =="
        self.assertEqual(self.uut.oper_eq(1), 32, "==")

    def test_62(self):
        "Inline operator: !="
        self.assertEqual(self.uut.oper_noteq(1), 33, "!=")

    def test_63(self):
        "Inline operator: >"
        self.assertEqual(self.uut.oper_greater(1), 35, ">")

    def test_64(self):
        "Inline operator: <"
        self.assertEqual(self.uut.oper_less(1), 34, "<")

    def test_65(self):
        "Inline operator: >="
        self.assertEqual(self.uut.oper_ge(1), 37, ">=")

    def test_66(self):
        "Inline operator: <="
        self.assertEqual(self.uut.oper_le(1), 36, "<=")

    def test_67(self):
        "Inline operator: &&"
        self.assertEqual(self.uut.oper_land(1), 38, "&&")

    def test_68(self):
        "Inline operator: ||"
        self.assertEqual(self.uut.oper_lor(1), 39, "||")

    def test_69(self):
        "Passing arguments by reference"
        self.assertEqual(self.uut.sample_reference(1, 2.2, 3.3), 6)

    def test_70(self):
        "Returning by reference"
        self.assertEqual(self.uut.refret_int(), self.uut.sample_int);
        self.assertEqual(self.uut.refret_double(), self.uut.sample_double);
        self.assertEqual(self.uut.refret_int(), -3333);
        self.assertEqual(self.uut.refret_double(), 7777);

if __name__ == '__main__':

    suite = unittest.TestLoader().loadTestsFromTestCase(test_3_methods)
    result=python_runner.BasicTestRunner(iterations=len(sys.argv)>1 and sys.argv[1] or 1,
	stream=len(sys.argv)>2 and open(sys.argv[2], "w") or sys.stderr).run(suite)
    sys.exit(not result.wasSuccessful())
